using System.IO;
using System.Text;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using FireStarterModeller.Test.BO;
using NUnit.Framework;
using Rhino.Mocks;

namespace FireStarterModeller.Test.Logic
{
    [Ignore("//TODO Brett 29 Jan 2009: The persister needs to be reviewed with new relationships")]
    [TestFixture]
    public class TestProjectPersistor: TestBase
    {
        private XmlPersistor CreateXmlPersistor()
        {
            return CreateXmlPersistor(new StringBuilder());
        }

        private static XmlPersistor CreateXmlPersistor(StringBuilder stringBuilder)
        {
            return new XmlPersistor(new StringWriter(stringBuilder));
        }
        public static DMSolution CreateSavedDMSolution()
        {
            DMSolution dmSolution = CreateUnsavedValidDMSolution();
            dmSolution.Save();
            return dmSolution;
        }
        public static DMSolution CreateUnsavedValidDMSolution()
        {
            DMSolution dmSolution = new DMSolution();
            dmSolution.SolutionName = SharedTestUtils.GetRandomString(2, 8);
            dmSolution.SolutionDirectory = SharedTestUtils.GetRandomString();
            dmSolution.DefaultAssembly = SharedTestUtils.CreateUnsavedValidProjectAssemblyInfo(dmSolution);

            return dmSolution;
        }

        [Test]
        public void Test_Persist_CallsThrough()
        {
            //---------------Set up test pack-------------------
            MockRepository mock = new MockRepository();
            IBoPersistor boPersistor = mock.StrictMock<IBoPersistor>();
            ProjectPersistor projectPersistor = new ProjectPersistor(boPersistor);
            //-------------Assert Preconditions -------------
            Expect.Call(delegate() { boPersistor.Persist(); }).Repeat.Once();
            mock.ReplayAll();
            //---------------Execute Test ----------------------
            projectPersistor.Persist();
            //---------------Test Result -----------------------
            mock.VerifyAll();
        }

        [Test]
        public void Test_BoPersistor_ReturnsConstructedInstance()
        {
            //---------------Set up test pack-------------------
            MockRepository mock = new MockRepository();
            IBoPersistor boPersistor = mock.StrictMock<IBoPersistor>();
            //-------------Assert Preconditions -------------
            mock.ReplayAll();
            //---------------Execute Test ----------------------
            ProjectPersistor projectPersistor = new ProjectPersistor(boPersistor);
            //---------------Test Result -----------------------
            mock.VerifyAll();
            Assert.AreSame(boPersistor, projectPersistor.BoPersistor);
        }

        [Test]
        public void Test_AddProject_NoBos()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            //-------------Assert Preconditions -------------
            Assert.AreEqual(0, dmSolution.AllClasses.Count);
            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(2, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneProjectAssembly()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            SharedTestUtils.CreateDMAssembly(dmSolution);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(3, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OnePropertyType()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            SharedTestUtils.CreateSavedPropertyTypeInfo(dmSolution);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(2, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneControlType()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            SharedTestUtils.CreateSavedUIControlTypeInfo(dmSolution);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(3, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneControlMapperType()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            SharedTestUtils.CreateSavedUIControlMapperTypeInfo(dmSolution);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(3, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneGridColumnControlType()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            SharedTestUtils.CreateSavedUIGridColumnControlTypeInfo(dmSolution);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(3, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneBo()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(3, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_TwoBos()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(4, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneBo_TwoProps()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            DMClass dmClass = SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            SharedTestUtils.CreateSavedDMProperty(dmClass);
            SharedTestUtils.CreateSavedDMProperty(dmClass);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(5, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneBo_TwoRelationships()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            DMClass dmClass = SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            SharedTestUtils.CreateSavedRelatedPropertyInfo(SharedTestUtils.CreateSavedRelationshipInfo(dmClass));
            SharedTestUtils.CreateSavedRelatedPropertyInfo(SharedTestUtils.CreateSavedRelationshipInfo(dmClass));
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(11, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneBo_PrimaryKey_TwoProps()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            DMClass dmClass = SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            DMProperty property = SharedTestUtils.CreateSavedDMProperty(dmClass);
            SharedTestUtils.CreateSavedDMProperty(dmClass);
            DMObjectIdentity primaryKey = SharedTestUtils.CreateSavedObjectIdentityInfo(dmClass);
            property.ObjectIdentity = primaryKey;
            property.Save();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(7, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneBo_OneUniqueConstraint()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            DMClass dmClass = SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            DMUniqueConstraint dmUniqueConstraint = SharedTestUtils.CreateSavedUniqueConstraintInfo(dmClass);
            SharedTestUtils.CreateSavedUniqueConstraintPropertyInfo(dmUniqueConstraint);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(6, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneBo_OneProp_WithTwoRules()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            DMClass dmClass = SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            DMProperty property = SharedTestUtils.CreateSavedDMProperty(dmClass);
            SharedTestUtils.CreateSavedPropRuleInfo(property);
            SharedTestUtils.CreateSavedPropRuleInfo(property);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(6, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneBo_OneProp_WithLookup()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            DMClass dmClass = SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            DMProperty property = SharedTestUtils.CreateSavedDMProperty(dmClass);
            DMLookupListSimple lookupListSimple = SharedTestUtils.CreateSavedSimpleLookupListInfo();
            property.LookupList = lookupListSimple;
            property.Save();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(5, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneBo_OneProp_WithLookupWithTwoItems()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            DMClass dmClass = SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            DMProperty property = SharedTestUtils.CreateSavedDMProperty(dmClass);
            DMLookupListSimple lookupListSimple = SharedTestUtils.CreateSavedSimpleLookupListInfo();
            SharedTestUtils.CreateSavedItemInfo(lookupListSimple);
            SharedTestUtils.CreateSavedItemInfo(lookupListSimple);
            property.LookupList = lookupListSimple;
            property.Save();
            
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(7, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneBo_TwoProps_UIGridDef()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            DMClass dmClass = SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            SharedTestUtils.CreateSavedDMProperty(dmClass);
            SharedTestUtils.CreateSavedDMProperty(dmClass);
            UIView uiView = new UIView();
            uiView.Class = dmClass;
            uiView.Save();
            UIGridInfo uiGridInfo = new UIGridInfo();
            uiGridInfo.UIView = uiView;
            uiGridInfo.Save();
            SharedTestUtils.CreateSavedUIColumnInfo(uiGridInfo);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(9, xmlPersistor.BusinessObjects.Count);
        }

        [Test]
        public void Test_AddProject_OneBo_TwoProps_UIFormDef()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);
            DMSolution dmSolution = CreateSavedDMSolution();
            DMClass dmClass = SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            SharedTestUtils.CreateSavedDMProperty(dmClass);
            SharedTestUtils.CreateSavedDMProperty(dmClass);
            UIView uiView = new UIView();
            uiView.Class = dmClass;
            uiView.Save();
            UIFormInfo uiFormInfo = new UIFormInfo();
            uiFormInfo.UIView = uiView;
            uiFormInfo.Save();
            UITab uiTab = new UITab();
            uiTab.UIFormInfo = uiFormInfo;
            uiTab.Name = SharedTestUtils.GetRandomString();
            uiTab.Save();
            UIColumnLayout uiColumnLayout = new UIColumnLayout();
            uiColumnLayout.UITab = uiTab;
            uiColumnLayout.UIForm = uiFormInfo;
            uiColumnLayout.Save();
            SharedTestUtils.CreateSavedUIField(uiColumnLayout);


            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(11, xmlPersistor.BusinessObjects.Count);
        }

        /// <summary>
        /// Tests a complex setup of objects with the persistor:
        /// -DMSolution
        ///     |-DMClass
        ///     |   |-Property (PK)
        ///     |   |-Property (LU - 2 Items)
        ///     |   |-Property
        ///     |   |-Relationship (Single)
        ///     |       |-Relationship Prop
        ///     |
        ///     |-DMClass
        ///         |-Property (PK)
        ///         |-Property
        ///         |-Relationship (Multiple)
        ///         |   |-Relationship Prop
        ///         |-Alternate Key
        ///             |-Alternate Key Prop
        /// </summary>
        [Test]
        public void Test_AddProject_Acceptance()
        {
            //---------------Set up test pack-------------------
            XmlPersistor xmlPersistor = CreateXmlPersistor();
            ProjectPersistor projectPersistor = new ProjectPersistor(xmlPersistor);

            DMSolution dmSolution = CreateSavedDMSolution();

            DMClass dmClassInfo1 = SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            DMProperty propertyInfo1_PK = SharedTestUtils.CreateSavedDMProperty(dmClassInfo1);
            DMProperty propertyInfo1_Rel = SharedTestUtils.CreateSavedDMProperty(dmClassInfo1);
            DMProperty propertyInfo1_LU = SharedTestUtils.CreateSavedDMProperty(dmClassInfo1);
            propertyInfo1_PK.ObjectIdentity = SharedTestUtils.CreateSavedObjectIdentityInfo(dmClassInfo1);
            propertyInfo1_PK.Save();

            DMLookupListSimple lookupListSimpleInfo1 = SharedTestUtils.CreateSavedSimpleLookupListInfo();
            SharedTestUtils.CreateSavedItemInfo(lookupListSimpleInfo1);
            SharedTestUtils.CreateSavedItemInfo(lookupListSimpleInfo1);
            propertyInfo1_LU.LookupList = lookupListSimpleInfo1;
            propertyInfo1_LU.Save();

            DMClass dmClassInfo2 = SharedTestUtils.CreateSavedDMClass(dmSolution.DefaultAssembly);
            DMProperty propertyInfo2_PK = SharedTestUtils.CreateSavedDMProperty(dmClassInfo2);
            DMProperty propertyInfo2_AK = SharedTestUtils.CreateSavedDMProperty(dmClassInfo2);
            propertyInfo2_PK.ObjectIdentity = SharedTestUtils.CreateSavedObjectIdentityInfo(dmClassInfo2);
            propertyInfo2_PK.Save();

            DMUniqueConstraint dmUniqueConstraintInfo2 = SharedTestUtils.CreateSavedUniqueConstraintInfo(dmClassInfo2);
            DMUniqueConstraintProperty dmUniqueConstraintPropertyInfo2 = SharedTestUtils.CreateSavedUniqueConstraintPropertyInfo(dmUniqueConstraintInfo2);
            dmUniqueConstraintPropertyInfo2.Property = propertyInfo2_AK;
            dmUniqueConstraintPropertyInfo2.Save();

            DMRelationship dmRelationshipInfo1 = SharedTestUtils.CreateSavedRelationshipInfo(dmClassInfo1);
            DMRelationshipProperty dmRelationshipProperty = SharedTestUtils.CreateSavedRelatedPropertyInfo(dmRelationshipInfo1);
            dmRelationshipProperty.OwnerProperty = propertyInfo1_Rel;
            dmRelationshipProperty.RelatedProperty = propertyInfo2_PK;
            dmRelationshipProperty.Save();

            DMRelationship dmRelationshipInfo2 = SharedTestUtils.CreateSavedRelationshipInfo(dmClassInfo2);
            DMRelationshipProperty dmRelationshipProperty2 = SharedTestUtils.CreateSavedRelatedPropertyInfo(dmRelationshipInfo2);
            dmRelationshipProperty2.OwnerProperty = propertyInfo2_PK;
            dmRelationshipProperty2.RelatedProperty = propertyInfo1_Rel;
            dmRelationshipProperty2.Save();
            
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            projectPersistor.AddProject(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(26, xmlPersistor.BusinessObjects.Count);
        }
    }
}
